package com.zhouwr.common.metadata;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhouwr.common.enums.ModelDataType;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @program: forallcn-iotps
 * @description:
 * @author: zhouwr
 * @create: 2020-11-26 22:34
 * @version：1.0
 **/
@Getter
@Setter
@Slf4j
@AllArgsConstructor
@NoArgsConstructor
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class ArrayData extends AbstractData<ArrayData> implements DataType, Converter<List<Object>> {
    private static final long serialVersionUID = 1L;
    @JSONField
    private ModelDataType type = ModelDataType.ARRAY;

    private Integer arraySize = 0;
    private ModelDataType arrayType;
    private String arraySplit = " ";
    private List<Object> value = new ArrayList<>();

    @Override
    public Object format(Object value) {
        if (arrayType != null && value instanceof Collection) {
            Collection < ?>collection = ((Collection<?>) value);
            return StringUtils.join(collection.stream()
                .map(data -> {
                    return arrayType.getDataType().get().format(data);
                })
            .collect(Collectors.toList()), this.arraySplit);
        }
        return JSONArray.toJSON(value);
    }

    @Override
    public List<Object> convert(Object value) {
        log.info("{} instanceof {} => {}  ===> {}", value, "Collection", (value instanceof Collection), value);
        if (value instanceof Collection) {
            this.value = ((Collection<?>) value)
                    .stream()
                    .map(val -> ((Converter<?>) arrayType.getDataType().get()).convert(val))
                    .collect(Collectors.toList());
        } else if(value instanceof String){
            this.value = Arrays.stream(String.valueOf(value).split(this.arraySplit))
                    .map(val -> ((Converter<?>) arrayType.getDataType().get()).convert(val))
                    .collect(Collectors.toList());
        } else {
            this.value = Collections.singletonList(value);
        }
        return this.value;
    }

    @Override
    public ValidateResult validate(Object value) {
        List<Object> listValue = convert(value);
        if (value instanceof Collection) {
            for (Object data : listValue) {
                ValidateResult result = arrayType.getDataType().get().validate(data);
                if (!result.isSuccess()) {
                    return result;
                }
            }
        }
        return ValidateResult.success(listValue);
    }

    public static void main(String[] args) throws Exception {
        Integer i = 1;
        ArrayData arrayData = new ArrayData(ModelDataType.INT, 2, ModelDataType.BYTE, " ", Arrays.asList(1,2));
        System.out.println(JSON.toJSON(arrayData));
//        System.out.println(arrayData.format(Arrays.asList(1,2)));

//        List<Object> convert = ((ArrayData) arrayData).convert(Arrays.asList(1, 2, 3));
//        System.out.println(convert);

        List<Object> convert1 = arrayData.convert("01 02 02 03");
        System.out.println(convert1);
        System.out.println(JSON.toJSON(arrayData));

        String join = StringUtils.join(" ", convert1);
        System.out.println(join);

        System.out.println(convert1 instanceof Collection);

        System.out.println(Collections.singletonList("01 03 00 00 00 7A C4 29"));
//        Object array = ((Converter<?>) ModelDataType.of("array").getDataType().get()).convert("01 03 00 00 00 7A C4 29");
//        System.out.println(array);

        String jsonString =
                "{\n" +
                        "  \"type\": \"array\",\n" +
                        "  \"arraySize\": 8,\n" +
                        "  \"arrayType\": \"byte\",\n" +
                        "  \"arraySplit\": \" \",\n" +
                        "  \"value\": [\n" +
                        "    1,\n" +
                        "    3,\n" +
                        "    0,\n" +
                        "    0,\n" +
                        "    0,\n" +
                        "    122,\n" +
                        "    -60,\n" +
                        "    41\n" +
                        "  ]\n" +
                        "}";
        ObjectMapper mapper = new ObjectMapper();
        ArrayData arrayData1 = mapper.readValue(jsonString, ArrayData.class);
        System.out.println(arrayData1);

    }
}
